﻿/*
 * Copyright (C) 2023 - 2024 lchfj.cn
 * 
 * This file is part of FastestHost.
 * 
 * FastestHost is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 * 
 * FastestHost is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License along with FastestHost. If not, see <https://www.gnu.org/licenses/>.
 */

using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Cn.Lchfj.FastestHost
{
    [JsonSerializable(typeof(HostIP))]
    [JsonSourceGenerationOptions(JsonSerializerDefaults.Web)]
    internal partial class HostIPJsonContext : JsonSerializerContext
    {

    }

    internal class HostIPDistinctCompare : IEqualityComparer<HostIP>
    {
        public static HostIPDistinctCompare Instance { get; } = new();
        private HostIPDistinctCompare()
        {
        }

        public virtual bool Equals(HostIP? x, HostIP? y)
        {
            if (x is null)
            {
                if (y is null)
                    return true;

                return false;
            }

            if (y is null)
                return false;

            return x.Host == y.Host && x.IP == y.IP;
        }

        public virtual int GetHashCode([DisallowNull] HostIP obj)
        {
            return HashCode.Combine(obj.Host, obj.IP);
        }
    }

    /// <summary>
    /// Hosts文件中的一行信息
    /// </summary>
    internal record HostIP
    {

        public static string Suffix { get; } = "# Added By FastestHost";

        private string host;
        private string ip;

        /// <summary>
        /// 主机名
        /// </summary>
        public string Host { get => host; init => host = value?.Trim().ToLower() ?? string.Empty; }

        /// <summary>
        /// IP地址
        /// </summary>
        public string IP { get => ip; init => ip = value?.Trim().ToLower() ?? string.Empty; }

        /// <summary>
        /// IP来源（0：域名解析；1：远程获取）
        /// </summary>
        public int IPFrom { get; init; }

        public HostIP()
        {
            host = string.Empty;
            ip = string.Empty;
        }

        public HostIP ToHostIP()
        {
            return new HostIP(this);
        }

        public string ToHostsLineString()
        {
            return string.Join(' ', IP, Host, Suffix);
        }

        public static bool TryParse(string text, [NotNullWhen(true)] out HostIP? value)
        {
            value = null;

            if (text[0] == '#')
                return false;

            var index = text.IndexOfAny(['\t', ' ']);
            if (index == -1)
                return false;



            var ip = text[..index];
            var host = text[index..];
            var remark = string.Empty;


            var indexRemark = host.IndexOf('#');
            if (indexRemark > -1)
            {
                remark = host[indexRemark..];
                host = host[..indexRemark];
            }

            if (string.IsNullOrWhiteSpace(ip))
                return false;
            if (string.IsNullOrWhiteSpace(host))
                return false;


            if (!IPAddress.TryParse(ip, out var _))
                return false;

            value = new() { Host = host, IP = ip, IPFrom = 0 };
            return true;
        }
    }
}
